using System;
using System.Collections.Generic;
using System.Text;

using System.IO;
using System.Xml;

namespace Adoor.Mapping
{
    public class ConfigVisitor : IVisitor
    {

        public ConfigVisitor(Stream configStream)
        {
            this.ConfigStream = configStream;

            XmlTextWriter writer = new XmlTextWriter(ConfigStream, Encoding.Unicode);
            
        }

        private XmlTextWriter writer;

        public XmlTextWriter Writer
        {
            get { return writer; }
            set { writer = value; }
        }
 
        private Stream configStream;

        public Stream ConfigStream
        {
            get { return configStream; }
            set { configStream = value; }
        }



        #region IVisitor Members
        void IVisitor.CloseConfig() {
            Writer.WriteFullEndElement();
            Writer.WriteEndDocument(); 
        }

        void IVisitor.Visit(Type type)
        {
            writer.WriteStartDocument();
            //<TIERS mapping:dummy="" typing:dummy="" UML:dummy="" xmlns:mapping="urn:xmd-mapping" xmlns:UML="href://org.omg/UML/1.3" xmlns:typing="urn:xmd-typing">

            writer.WriteStartElement(type.Name);
            writer.WriteAttributeString("dummy", "mapping", "");
            writer.WriteAttributeString("dummy", "UML", "");
            writer.WriteAttributeString("mapping", "xmlns", "urn:xmd-mapping");
            writer.WriteAttributeString("UML", "xmlns", "href://org.omg/UML/1.3");
            writer.WriteAttributeString("typing", "xmlns", "urn:xmd-typing");

        }
        void IVisitor.Visit(Adoor.Mapping.Attributes.EntityAttribute attribute)
        {
             //<Lieu>
            //<typing:entity type="Adoor.Domain.Tiers.Lieu, Adoor.Domain.Tiers" classId="100" key_Manager="Adoor.Object.Relational.Suffixkey_Manager, Adoor.Object.Relational"
            //<mapping:entity class="Adoor.Object.Relational.EntityTableFactory, Adoor.Object.Relational" table="Lieu" distinctMode="Emulated">
            //
            writer.WriteStartElement(attribute.EntityType.Name);

            writer.WriteStartElement("entity", "mapping");
            writer.WriteAttributeString("class", attribute.ProviderClass.FullName);
            writer.WriteAttributeString("classId", attribute.ClassId.ToString() );
            writer.WriteAttributeString("key_Manager", attribute.KeyManager.FullName);
            writer.WriteEndElement();

            writer.WriteStartElement("entity", "typing");
            writer.WriteAttributeString("type", attribute.EntityType.FullName);
            writer.WriteAttributeString("table", attribute.Table);
            writer.WriteAttributeString("distinctMode", attribute.DictinctMode.ToString());
            writer.WriteEndElement(); 
            
            //writer.WriteEndElement();  omit it
            
        }

        void IVisitor.Visit(Adoor.Mapping.Attributes.KeyAttribute attribute, System.Reflection.MemberInfo member)
        {
            /*
             * <mapping:key class="Adoor.Object.Relational.SmartKeyFactory, Adoor.Object.Relational" primaryKey="ID_lieu" sqlStatement="SELECT CLASSID FROM ITCLASSES WHERE CLASSNAME='Lieu'">
      </mapping:key>
             */
            writer.WriteStartElement("key", "mapping");
            writer.WriteAttributeString("class", attribute.ProviderClass.FullName);
            writer.WriteAttributeString("primaryKey", attribute.PrimaryKey);
            writer.WriteAttributeString("sqlStatement", attribute.SqlStatement);
            writer.WriteEndElement(); 
            
            writer.WriteEndElement(); //this one comes from entity typing
        }

        void IVisitor.Visit(Adoor.Mapping.Attributes.PropertyAttribute attribute, System.Reflection.MemberInfo member)
        {
            /*
             /*<CodePostal xmlns:env="urn:xmd-environment">
      <typing:property type="System.String">
      </typing:property>
      <mapping:property readOnly="false" column="code_postal" length="30">
      </mapping:property>
    </CodePostal>

             */
            writer.WriteStartElement(member.Name);
            writer.WriteAttributeString("env","xmlns","urn:xmd-environment");
            
            writer.WriteStartElement("property", "typing");
            Writer.WriteAttributeString("type", attribute.PropertyType.Name);
            Writer.WriteEndElement();

            writer.WriteStartElement("property", "mapping");
            Writer.WriteAttributeString("readOnly", attribute.Readonly.ToString());
            Writer.WriteAttributeString("column", attribute.Column);
            Writer.WriteAttributeString("length", attribute.Length.ToString() );
            Writer.WriteEndElement();

            Writer.WriteEndElement();
        }

        void IVisitor.Visit(Adoor.Mapping.Attributes.OneToManyAttribute attribut, System.Reflection.MemberInfo member)
        {
            /*
         <Lieu>
      <typing:reference navigable="false" type="Adoor.Domain.Tiers.Lieu, Adoor.Domain.Tiers" target="Lieu" multiplicity="1" adjacentMultiplicity="*" parent="Adresse" xmlns:env="urn:xmd-environment" />
      <mapping:reference stored="true" class="Adoor.Object.Relational.ForeignKeyFactory, Adoor.Object.Relational" foreignKey="id_Lieu" type="System.String" xmlns:env="urn:xmd-environment" />
    </Lieu>
         */
            System.Reflection.PropertyInfo prop = (System.Reflection.PropertyInfo) member;
            writer.WriteStartElement(member.Name);

            writer.WriteStartElement("reference", "typing");
            Writer.WriteAttributeString("navigable", attribut.Navigable.ToString());
            Writer.WriteAttributeString("type", prop.PropertyType.FullName);
            Writer.WriteAttributeString("target", attribut.Target);
            Writer.WriteAttributeString("multiplicity", attribut.Multiplicity.ToString());
            Writer.WriteAttributeString("adjacentMultiplicity", attribut.AdjacentMultiplicity.ToString());
            Writer.WriteAttributeString("parent", attribut.Parent);
            writer.WriteAttributeString("env", "xmlns", "urn:xmd-environment");
            Writer.WriteEndElement();

            writer.WriteStartElement("reference", "mapping");
            Writer.WriteAttributeString("stored", attribut.Stored.ToString());
            Writer.WriteAttributeString("class", attribut.ProviderClass.ToString());
            Writer.WriteAttributeString("foreignKey", attribut.ForeignKeyColumn);
            Writer.WriteAttributeString("type", attribut.ForeignKeyType.Name);
            writer.WriteAttributeString("env", "xmlns", "urn:xmd-environment");
            Writer.WriteEndElement();

            Writer.WriteEndElement();
        }
        #endregion
    }
}
